package com.iot08.api.service;

import com.aliyun.tea.utils.StringUtils;
import com.iot08.api.response.ProductInfoResp;
import com.iot08.api.response.VipPrivilegeResp;
import com.iot08.api.utils.StringTool;
import com.iot08.api.vo.request.AddProductInfoReqVo;
import com.iot08.api.vo.request.VersionVo;
import com.iot08.common.entity.app.ProductInfo;
import com.iot08.common.entity.app.VipMember;
import com.iot08.common.entity.app.VipPrivilege;
import com.iot08.common.service.base.BaseAdminService;
import com.iot08.common.utils.DateUtil;
import com.iot08.common.utils.response.ResponseEnum;
import com.iot08.common.utils.response.ResponseMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author cwj
 * @description
 * @date 2024/12/30 13:28
 **/
@Slf4j
@Service
public class ProductInfoService extends BaseAdminService<ProductInfo> {

    @Resource
    private VipPrivilegeService vipPrivilegeService;

    @Autowired
    @Lazy
    private VipMemberService vipMemberService;

    @Value("${support.discount.lowest.version}")
    private String supportDiscountLowestVersion;

    @Value("${support.discount.lowest.ios.version}")
    private String supportDiscountLowestIosVersion;



    /**
     * @description 添加产品信息
     * @author cwj
     * @param [vo]
     * @return com.iot08.common.utils.response.ResponseMap
     * @date @time 2024/12/30 18:18
     **/
    public ResponseMap addProductInfo(AddProductInfoReqVo vo){
        //检查同产品类型产品是否存在，如果存在则不能添加
        //ProductInfo productInfo =  this.findOne(new Query(new Criteria().orOperator( Criteria.where("name").is(vo.getName()), Criteria.where("type").is(vo.getType()))).limit(1));
        ProductInfo productInfo =  this.findOne(new Query(new Criteria().orOperator(Criteria.where("name").is(vo.getName())
                        .and("sysType").is(vo.getSysType()).and("isCurrentUsing").is(vo.getIsCurrentUsing()),
                Criteria.where("type").is(vo.getType()).and("sysType").is(vo.getSysType())
                        .and("isCurrentUsing").is(vo.getIsCurrentUsing()))).limit(1));
        productInfo = null;
        if(ObjectUtils.isEmpty(productInfo)){
            productInfo = new ProductInfo();
            productInfo.setApplePayProdId(vo.getApplePayProdId());
            productInfo.setName(vo.getName());
            productInfo.setType(vo.getType());
            productInfo.setTypeDesc(vo.getTypeDesc());
            productInfo.setDesc(vo.getDesc());
            productInfo.setPrivilegeIds(vo.getPrivilegeIds());
            productInfo.setPrice(vo.getPrice());
            productInfo.setPriceDesc(vo.getPriceDesc());
            productInfo.setOriginalPrice(vo.getOriginalPrice());
            productInfo.setOriginalPriceDesc(vo.getOriginalPriceDesc());
            productInfo.setCurrency(vo.getCurrency());
            productInfo.setMonetaryUnit(vo.getMonetaryUnit());
            productInfo.setIsRecommend(vo.getIsRecommend());
            productInfo.setSysType(vo.getSysType());
            productInfo.setDiscount(vo.getDiscount());
            productInfo.setDiscountDesc(vo.getDiscountDesc());
            productInfo.setSequence(vo.getSequence());
            if(!StringUtils.isEmpty(vo.getDiscountStartTime())){
                productInfo.setDiscountStartTime(DateUtil.strToTimestamp(vo.getDiscountStartTime(),DateUtil.FORMAT_1)/1000);
            }
            if(!StringUtils.isEmpty(vo.getDiscountEndTime())) {
                productInfo.setDiscountEndTime(DateUtil.strToTimestamp(vo.getDiscountEndTime(), DateUtil.FORMAT_1)/1000);
            }
            productInfo.setPayGoldCoinDiscount(vo.getPayGoldCoinDiscount());
            productInfo.setGoldCoinDiscountDesc(vo.getGoldCoinDiscountDesc());
            productInfo.setIsCurrentUsing(vo.getIsCurrentUsing());
            productInfo.setSequence(vo.getSequence());
            productInfo.setIsBrokenScreenInsurance(vo.getIsBrokenScreenInsurance());
            productInfo.setBrokenScreenInsuranceDesc(vo.getBrokenScreenInsuranceDesc());
            productInfo.setFirstRechargeFlag(vo.getFirstRechargeFlag());
            productInfo.setCreateTime(new Date());
            productInfo.setUpdateTime(new Date());
            this.save(productInfo);
        }else {
            return ResponseMap.fail( ResponseEnum.STATUS400.getCode(),"API.response.product.result.fail");
        }
        return ResponseMap.success();
    }


    /**
     * @description 修改产品信息
     * @author cwj
     * @param [vo]
     * @return com.iot08.common.utils.response.ResponseMap
     * @date @time 2024/12/31 14:13
     **/
    public ResponseMap editProductInfo(AddProductInfoReqVo vo) {
        Update update = new Update();
        update.set("updateTime",new Date());
        if(!StringUtils.isEmpty(vo.getApplePayProdId())){
            update.set("applePayProdId",vo.getApplePayProdId());
        }
        if(ObjectUtils.isNotEmpty(vo.getIsRecommend())) {
            update.set("isRecommend",vo.getIsRecommend());
        }
        if(ObjectUtils.isNotEmpty(vo.getPrice())) {
            update.set("price",vo.getPrice());
        }
        if(!StringUtils.isEmpty(vo.getDiscountDesc())) {
            update.set("priceDesc",vo.getPriceDesc());
        }
        if(ObjectUtils.isNotEmpty(vo.getOriginalPrice())) {
            update.set("originalPrice",vo.getOriginalPrice());
        }
        if(!StringUtils.isEmpty(vo.getOriginalPriceDesc())) {
            update.set("originalPriceDesc",vo.getOriginalPriceDesc());
        }
        if(!StringUtils.isEmpty(vo.getCurrency())) {
            update.set("currency", vo.getCurrency());
        }
        if(!StringUtils.isEmpty(vo.getMonetaryUnit())) {
            update.set("monetaryUnit",vo.getMonetaryUnit());
        }
        if(ObjectUtils.isNotEmpty(vo.getSysType())) {
            update.set("sysType",vo.getSysType());
        }
        if(ObjectUtils.isNotEmpty(vo.getDiscount())){
            update.set("discount",vo.getDiscount());
        }
        if(!StringUtils.isEmpty(vo.getDiscountDesc())){
            update.set("discountDesc",vo.getDiscountDesc());
        }
        if(!StringUtils.isEmpty(vo.getDiscountStartTime())){
            update.set("discountStartTime",DateUtil.strToTimestamp(vo.getDiscountStartTime(),DateUtil.FORMAT_1)/1000);
        }
        if(!StringUtils.isEmpty(vo.getDiscountEndTime())) {
            update.set("discountEndTime", DateUtil.strToTimestamp(vo.getDiscountEndTime(), DateUtil.FORMAT_1)/1000);
        }
        if(ObjectUtils.isNotEmpty(vo.getPayGoldCoinDiscount())) {
            update.set("payGoldCoinDiscount",vo.getPayGoldCoinDiscount());
        }
        if(!StringUtils.isEmpty(vo.getGoldCoinDiscountDesc())) {
            update.set("goldCoinDiscountDesc",vo.getGoldCoinDiscountDesc());
        }
        if(ObjectUtils.isNotEmpty(vo.getIsCurrentUsing())) {
            update.set("isCurrentUsing",vo.getIsCurrentUsing());
        }
        if(ObjectUtils.isNotEmpty(vo.getSequence())) {
            update.set("sequence",vo.getSequence());
        }
        if(ObjectUtils.isNotEmpty(vo.getIsBrokenScreenInsurance())) {
            update.set("isBrokenScreenInsurance",vo.getIsBrokenScreenInsurance());
        }
        if(!StringUtils.isEmpty(vo.getBrokenScreenInsuranceDesc())) {
            update.set("brokenScreenInsuranceDesc",vo.getBrokenScreenInsuranceDesc());
        }
        if(ObjectUtils.isNotEmpty(vo.getFirstRechargeFlag())) {
            update.set("firstRechargeFlag",vo.getFirstRechargeFlag());
        }
        this.updateById(new ObjectId(vo.getPId()),update);
        return ResponseMap.success();
    }


    /**
     * @description 查询所有产品信息
     * @author cwj
     * @param []
     * @return com.iot08.common.utils.response.ResponseMap
     * @date @time 2024/12/31 9:27
     **/
    public ResponseMap queryProductInfo(VersionVo versionVo,String openId){
        if(ObjectUtils.isEmpty(versionVo.getUserAgent())) {
            return ResponseMap.fail("参数不正确");
        }
        Query query = new Query();
        //包含最低版本
        //boolean isNewVersion;
        //不包含最低版本
        boolean isNewVer;
        boolean isAndroid = versionVo.getUserAgent().contains("Android");
        if(isAndroid) {
            int result = StringTool.compareVersions(versionVo.getVersion(), supportDiscountLowestVersion);
            //isNewVersion = result >= 0;
            isNewVer = result > 0;
        } else {
            int result = StringTool.compareVersions(versionVo.getVersion(),supportDiscountLowestIosVersion);
            //isNewVersion =  result >= 0;
            isNewVer = result > 0;
        }
        if(isAndroid) {
            //查询正在使用中安卓会员产品信息
            query.addCriteria(Criteria.where("sysType").is(3).and("isCurrentUsing").is(1));
        } else {
            if(isNewVer) {
                query.addCriteria(Criteria.where("sysType").is(2).and("isCurrentUsing").is(1));
            } else {
                query.addCriteria(Criteria.where("sysType").is(3).and("isCurrentUsing").is(1));
            }
        }
        query.with(Sort.by(Sort.Order.asc("sequence")));
        //查询产品信息
        List<ProductInfo> productInfos = this.find(query);
        List<VipPrivilege> privileges = vipPrivilegeService.queryAllVipPrivilege();

        //旧版本则去除新加的记录
        if(!isNewVer) {
            privileges = privileges.stream().limit(6).collect(Collectors.toList());
        }
        //用id为key转成map
        Map<String, VipPrivilege> privilegeMap = privileges.stream().collect(Collectors.toMap(VipPrivilege::getId, Function.identity()));
        // 构造响应列表
        List<ProductInfoResp> productInfoResps = productInfos.stream()
                .map(p -> {
                    ProductInfoResp pr = new ProductInfoResp();
                    pr.setPid(p.getId());
                    pr.setApplePayProdId(p.getApplePayProdId());
                    pr.setType(p.getType());
                    pr.setTypeDesc(p.getTypeDesc());
                    pr.setName(p.getName());
                    pr.setDesc(p.getDesc());
                    pr.setPrice(p.getPrice());
                    pr.setOriginalPrice(p.getOriginalPrice());
                    pr.setIsRecommend(p.getIsRecommend());
                    pr.setPriceDesc(p.getMonetaryUnit()+p.getPrice());
                    pr.setOriginalPriceDesc(p.getMonetaryUnit()+p.getOriginalPrice());
                    pr.setCurrency(p.getCurrency());
                    pr.setIsBrokenScreenInsurance(p.getIsBrokenScreenInsurance());
                    pr.setBrokenScreenInsuranceDesc(p.getBrokenScreenInsuranceDesc());
                    pr.setFirstRechargeFlag(p.getFirstRechargeFlag());
                    // 安全解析 privilegeIds
                    List<String> ids = Optional.ofNullable(p.getPrivilegeIds())
                                    .map(idsStr -> Arrays.asList(idsStr.split(",")))
                                    .orElse(Collections.emptyList());;
                    // 根据 privilegeIds 查找相关权限
                    List<VipPrivilegeResp> vipPrivileges = ids.stream()
                            .map(privilegeMap::get)
                            .filter(Objects::nonNull)
                            .map(this::convertToResp)
                            .collect(Collectors.toList());
                    pr.setVipPrivileges(vipPrivileges);
                    return pr;
                }).collect(Collectors.toList());
        //检查用户是否为未购买会员的用户，如果未购买，则给其显示首次购买的套餐
        VipMember vipMember = vipMemberService.queryVipMemberByOpenId(openId);
        if(isAndroid){
            productInfoResps = filterDataByFirstCharge(vipMember, productInfoResps,"4.9");
        } else {
            if(!isNewVer) {
                productInfoResps =  productInfoResps.stream()
                        .filter(p -> !(p.getPrice().compareTo(new BigDecimal("4.9")) == 0  || Integer.valueOf(4).equals(p.getType())))
                        .collect(Collectors.toList());
            } else{
                //根据是否为首充过滤数据
                productInfoResps = filterDataByFirstCharge(vipMember, productInfoResps,"5.0");
            }
        }
        ResponseMap res = ResponseMap.success();
        res.put("productInfos",productInfoResps);
        return res;
    }

    /**
     * @description 检查是否为首充
     * @author cwj
     * @param [vipMember, productInfoResps]
     * @return java.util.List<com.iot08.api.response.ProductInfoResp>
     * @date @time 2025/5/19 16:37
     **/
    private List<ProductInfoResp> filterDataByFirstCharge(VipMember vipMember, List<ProductInfoResp> productInfoResps,String firstPrice) {
        if(ObjectUtils.isEmpty(vipMember) || (Integer.valueOf(1).equals(vipMember.getIsOnTrialVip()) && StringUtils.isEmpty(vipMember.getOrderid()))) {
            productInfoResps =  productInfoResps.stream()
                    .filter(p -> !(p.getPrice().compareTo(new BigDecimal("9.9")) == 0  && Integer.valueOf(1).equals(p.getType())))
                    .collect(Collectors.toList());
        } else {
            productInfoResps =  productInfoResps.stream()
                    .filter(p -> !(p.getPrice().compareTo(new BigDecimal(firstPrice)) == 0  && Integer.valueOf(1).equals(p.getType())))
                    .collect(Collectors.toList());
        }
        return productInfoResps;
    }


    /**
     * @description 对象转换，VipPrivilege对象转VipPrivilegeResp对象
     * @author cwj
     * @param [privilege]
     * @return com.iot08.api.response.VipPrivilegeResp
     * @date @time 2024/12/31 10:09
     **/
    private VipPrivilegeResp convertToResp(VipPrivilege privilege) {
        VipPrivilegeResp vipPrivilegeResp = new VipPrivilegeResp();
        vipPrivilegeResp.setIcon(privilege.getIcon());
        vipPrivilegeResp.setName(privilege.getName());
        vipPrivilegeResp.setDesc(privilege.getDesc());
        vipPrivilegeResp.setIconUrl(privilege.getIconUrl());
        return vipPrivilegeResp;
    }

}
